<!-- 修改密码 -->
<!-- 修改密码 -->
<template>
  <div>
    <el-dialog v-model="dialogVisible" width="500" title="找回密码" alignCenter draggable appendToBody destroyOnClose lockScroll :closeOnClickModal="false">
      <el-form ref="elFormRef" :model="formData" :rules="rules" scrollToError statusIcon>
        <div>
          <!-- 用于防止密码自动填充 -->
          <input style="position: absolute; top: -100vh; left: -100vw; z-index: -1; width: 0; height: 0; padding: 0" />
          <input type="password" style="position: absolute; top: -100vh; left: -100vw; z-index: -1; width: 0; height: 0; padding: 0" />
        </div>
        <el-form-item label="账号" prop="username" required labelWidth="7em" style="margin-bottom: 30px">
          <el-input v-model="formData.username" :maxlength="usernameMax" placeholder="请输入账号" clearable></el-input>
        </el-form-item>
        <el-form-item label="绑定手机号" prop="phone" required labelWidth="7em" style="margin-bottom: 30px">
          <el-input
            v-model="formData.phone"
            :formatter="(val: string) => val.replace(/[^\d]/, '')"
            :parser="(val: string) => val.replace(/[^\d]/, '')"
            :maxlength="11"
            placeholder="请输入绑定手机号"
            clearable
          ></el-input>
        </el-form-item>
        <el-form-item label="验证码" prop="smsCode" required labelWidth="7em" style="margin-bottom: 30px">
          <el-input
            v-model="formData.smsCode"
            :formatter="(val: string) => val.replace(/[^\d]/, '')"
            :parser="(val: string) => val.replace(/[^\d]/, '')"
            type="text"
            :maxlength="smsCodeLen"
            placeholder="请输入验证码"
            clearable
          >
            <template #append>
              <base-count-down-button ref="baseCountDownButtonRef" style="width: 120px" @click="sendSmsCode"></base-count-down-button>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="新密码" prop="password" required labelWidth="7em" style="margin-bottom: 30px">
          <el-input v-model="formData.password" :maxlength="passwordMax" showPassword type="password" placeholder="请输入新密码" clearable></el-input>
        </el-form-item>
        <el-form-item label="确认密码" prop="affirmPassword" required labelWidth="7em" style="margin-bottom: 30px">
          <el-input v-model="formData.affirmPassword" :maxlength="passwordMax" showPassword type="password" placeholder="请再次输入新密码" clearable></el-input>
        </el-form-item>
        <el-form-item label="" style="margin-bottom: 30px">
          <el-button type="primary" style="width: 100%" @click="submit">提交</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
  import type { FormInstance, FormItemRule, FormRules } from 'element-plus';
  import { type FindPasswordRequest, SmsType, findPasswordAxios, sendAuthCodeByPhoneAxios } from '@/api/login';
  import { getPasswordRules, getPhoneRules, getSmsCodeRules, getUsernameRules } from '@/utils/page/rules';
  type FormData = FindPasswordRequest & { affirmPassword: string };

  const dialogVisible = ref(false);
  const elFormRef: Ref<FormInstance | null> = ref(null);
  const formData: FormData = reactive<FormData>({
    username: '',
    phone: '',
    smsCode: '',
    password: '',
    affirmPassword: '',
  });
  const { passwordMax, passwordRules } = getPasswordRules();
  const { phoneRules } = getPhoneRules();
  const { usernameRules, usernameMax } = getUsernameRules();
  const { smsCodeLen, smsCodeRules } = getSmsCodeRules();

  const baseCountDownButtonRef: $RefComp<'BaseCountDownButton'> = ref(null);
  const rules = computed<FormRules>(() => {
    const _rules: FormRules = {
      username: usernameRules,
      phone: phoneRules,
      smsCode: smsCodeRules,
      password: passwordRules('密码'),
      affirmPassword: passwordRules('确认密码'),
    };
    if (formData.password) {
      const regExp = RegExp(`^${formData.password}$`);
      const affirmRules: FormItemRule = { pattern: regExp, type: 'string', message: '两次输入密码不一致', trigger: ['blur', 'change'] };
      (_rules.affirmPassword as FormItemRule[]).push(affirmRules);
    }
    return _rules;
  });

  /**
   * 显示
   */
  function show(data: { username?: string }) {
    formData.username = data.username || '';
    dialogVisible.value = true;
  }

  /**
   * 隐藏
   */
  function hide() {
    dialogVisible.value = false;
  }

  /** 发送验证码 */
  async function sendSmsCode() {
    try {
      await elFormRef.value!.validateField('phone');
      baseCountDownButtonRef.value?.setLoadState(true);
      await sendAuthCodeByPhoneAxios(SmsType.AppSMSRESTPassword, formData.phone);
      baseCountDownButtonRef.value?.setLoadState(false);
      baseCountDownButtonRef.value?.start(); // 开始倒计时
    } catch (err) {
      baseCountDownButtonRef.value?.setLoadState(false);
      ElToast.error(err.msg || '验证码发送失败');
    }
  }

  /** 提交 */
  async function submit() {
    try {
      await elFormRef.value?.validate();
    } catch (error) {
      ElToast.error('提交失败，请完善表单，-BD002');
      return;
    }
    try {
      await findPasswordAxios({ username: formData.username, password: formData.password, phone: formData.phone, smsCode: formData.smsCode });
      ElToast.success('重置成功');
      hide();
    } catch (error) {
      ElToast.error(error.msg || '提交失败，-BD003');
    }
  }

  defineExpose({ show, hide });
</script>
